// HEAD ERROR H
/*==================================================================================================================
                  Copyright (C) 2013 SUMSCOPE L.P.
                  ALL RIGHTS RESERVED 
====================================================================================================================
File description:
    Define error code and error message

====================================================================================================================
...Date      Name                                  Description of Change
06-May-2013  James Xu                              Initial version
21-May-2013  James Xu                              Add STATISTICS_ANALYSIS_QUANTITY_UNSUFFICIENT
03-Jun-2013  James Xu                              Add ZERO_CURVE_SAMPLE_BONDS_QUANTITY_UNSUFFICIENT
$HISTORY$
===================================================================================================================*/
#ifndef SS_ERROR_H
#define SS_ERROR_H

#include <exception>
#include <sstream>

namespace SS 
{
    // Base error class
    class Error : public std::exception {
      public:
        // The explicit use of this constructor is not advised.
        //  Use the macro instead.
        Error(const std::string& file,
              long line,
              const std::string& functionName,
              const std::string& message = "");
        // The automatically generated destructor would
        //  not have the throw specifier.
        ~Error() throw() {}
        // Returns the error message.
        const char* what() const throw ();
      private:
        std::string message_;
    };

}

// Return predefined error message per given error code
std::string ErrorMessage(int errorCode);


#define  SS_NO_ERROR 0


// Yield Curve error 
#define  YIELD_CURVE_ERROR_BASE     2000

#define  YIELD_CURVE_SAMPLE_BONDS_QUANTITY_UNSUFFICIENT             YIELD_CURVE_ERROR_BASE + 1
#define  YIELD_CURVE_INTERPOLATED_POINTS_QUANTITY_UNSUFFICIENT      YIELD_CURVE_ERROR_BASE + 2
#define  YIELD_CURVE_CREDIT_BOND_DATA_LACKING_FIXING_POINT          YIELD_CURVE_ERROR_BASE + 3
#define  ZERO_CURVE_SAMPLE_BONDS_QUANTITY_UNSUFFICIENT              YIELD_CURVE_ERROR_BASE + 4



#define  STATISTICS_ANALYSIS_ERROR_BASE 1000
#define  STATISTICS_ANALYSIS_QUANTITY_UNSUFFICIENT      STATISTICS_ANALYSIS_ERROR_BASE + 1

// QL_FAIL
// Brief throw an error (possibly with file and line information)
#define SS_FAIL(message) \
do { \
    std::ostringstream _ql_msg_stream; \
    _ql_msg_stream << message; \
    throw SS::Error(__FILE__,__LINE__, \
                          __FUNCTION__,_ql_msg_stream.str()); \
} while (false)


// QL_ASSERT
// Brief throw an error if the given condition is not verified
#define SS_ASSERT(condition,message) \
if (!(condition)) { \
    std::ostringstream _ql_msg_stream; \
    _ql_msg_stream << message; \
    throw SS::Error(__FILE__,__LINE__, \
                          __FUNCTION__,_ql_msg_stream.str()); \
 } else 

// QL_REQUIRE
// Brief throw an error if the given pre-condition is not verified
#define SS_REQUIRE(condition,message) \
if (!(condition)) { \
    std::ostringstream _ql_msg_stream; \
    _ql_msg_stream << message; \
    throw SS::Error(__FILE__,__LINE__, \
                          __FUNCTION__,_ql_msg_stream.str()); \
 } else 

// SS_ENSURE
// Brief throw an error if the given post-condition is not verified
#define SS_ENSURE(condition,message) \
if (!(condition)) { \
    std::ostringstream _ql_msg_stream; \
    _ql_msg_stream << message; \
    throw SS::Error(__FILE__,__LINE__, \
                          __FUNCTION__,_ql_msg_stream.str()); \
 } else 

#endif